package com.file;

import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.List;
import java.util.UUID;
import java.util.zip.Adler32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class FileUtil {

    public final static String FILE_WINDOWS_PATH = "D:/java/java_code/file/";
    public final static String FILE_LINUX_PATH = "/home/file/";
    public final static String FILE_WEB_PATH = "/web/file/";

    public final static String FILE_DIVISION = "-";
    public final static String FORWARD_SLASH = "/";
    public final static String BACK_SLASH = "\\";
    public final static String SPOT = ".";

    public final static String DOC = ".doc";
    public final static String DOCX = ".docx";
    public final static String XLS = ".xls";
    public final static String XLSX = ".xlsx";
    public final static String PDF = ".pdf";
    public final static String HTML = ".html";
    public final static String WAV = ".wav";
    public final static String MP3 = ".mp3";
    public final static String JPG = ".jpg";
    public final static String PNG = "png";
    public final static String ZIP = ".zip";
    public final static String TXT = ".txt";
    public final static String HBZB = ".hbzb";
    public final static String HBCQ = ".hbcq";
    public final static String HBTB = ".hbtb";

    public final static int READ_SIZE = 1024*1024*10;
    public final static int WRITE_SIZE = 1024*1024*10;

    public static String getFileName(){
        return UUID.randomUUID().toString().replaceAll(FILE_DIVISION, "");
    }

    public static String getFileSuffix(String fileName){
        return fileName.substring(fileName.lastIndexOf(SPOT), fileName.length());
    }

    public static String getFileAlias(String fileName){
        return fileName.substring(0, fileName.lastIndexOf(SPOT));
    }

    public static String getFilePath(String date){
        String property = System.getProperty("os.name");
        String filePath = property.startsWith("Win")? FILE_WINDOWS_PATH:FILE_LINUX_PATH;
        return filePath + date + FORWARD_SLASH;
    }

    public static String getFileUrl(String date){
        return FILE_WEB_PATH + date + FORWARD_SLASH;
    }

    public static File createFile(String createPath) throws IOException {
        File file = new File(createPath);
        if (!file.getParentFile().exists()){
            file.getParentFile().mkdirs();
        }
        file.createNewFile();
        return file;
    }

    public static File createFile(String filePath, String fileName, String fileSuffix) throws IOException {
        return createFile(filePath + fileName + fileSuffix);
    }
    public static void deleteFile(String filePath) throws IOException {
        File file = new File(filePath);
        file.deleteOnExit();
        System.gc();
    }

    public static String readFile(String filePath) throws IOException {
        File file = new File(filePath);
        return readFile(file);
    }

    public static String readFile(File file) throws IOException {
        FileInputStream inputStream = new FileInputStream(file);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] bytes = new byte[READ_SIZE];
        for (int i = 0; (i = inputStream.read(bytes)) != -1;) {
            outputStream.write(bytes, 0,  i);
        }
        return new String(outputStream.toByteArray());
    }

    public static String readFile(MultipartFile multipartFile) throws IOException {
        InputStream inputStream = multipartFile.getInputStream();
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] bytes = new byte[READ_SIZE];
        for (int i = 0; (i = inputStream.read(bytes)) != -1;) {
            outputStream.write(bytes, 0,  i);
        }
        return new String(outputStream.toByteArray());
    }

    public static void writeFile(String createPath, String content) throws Exception {
        try (BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(
                new FileOutputStream(createPath))) {
            bufferedOutputStream.write(content.getBytes());
            bufferedOutputStream.flush();
        }
    }

    public static void writeFile(String createPath, String content, boolean append, boolean enter) throws Exception {
        try (BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(
                new FileOutputStream(createPath, append))) {
            bufferedOutputStream.write(content.getBytes());
            if (enter){
                String property = System.getProperty("line.separator");
                bufferedOutputStream.write(property.getBytes());
            }
            bufferedOutputStream.flush();
        }
    }

    public static void compressZip(String createPath, List<String> filePathList) throws Exception {
        try (OutputStream outputStream = new FileOutputStream(createPath);
             CheckedOutputStream checkedOutputStream = new CheckedOutputStream(outputStream, new Adler32());
             ZipOutputStream zipOut = new ZipOutputStream(checkedOutputStream)){
            for (String filePath : filePathList) {
                File file = new File(filePath);
                String content = readFile(file);
                // 写入数据并刷新
                zipOut.putNextEntry(new ZipEntry(file.getName()));
                zipOut.write(content.getBytes());
                zipOut.flush();
            }
        }
    }

}
